#include "GameControl/GameController.hh"
#include "GameControl/IGameController.hh"
#include "GameControl/GetEnemyPosition.hh"
#include "map.hh"
#include <memory>
#include <iostream>
#include <random>
#include <chrono>
#include <thread>

GameController::GameController(Player &p) : player(p)
{
    this->gameMap.generate_map();
}

void GameController::initializeItems()
{
    items.clear();
    collectedItems.clear();
}

int GameController::getLocationType(int x, int y) const
{
    if (x < 0 || x >= 9 || y < 0 || y >= 9)
        return 0;

    if (x == 0 && (y == 1 || y == 7))
        return 1; // Hall
    if (x == 1 && y == 8)
        return 6; // Stairwell
    if (x == 4 && y == 8)
        return 6; // Stairwell
    if (x == 7 && y == 8)
        return 6; // Stairwell
    if (x == 1 && y == 0)
        return 6; // Stairwell
    if (x == 4 && y == 0)
        return 6; // Stairwell
    if (x == 7 && y == 0)
        return 6;
    if ((x == 1 || x == 4 || x == 7) && y >= 1 && y <= 7)
        return 3;
    return 0;
}
void GameController::handleLocationEvents()
{
    int locationType = getLocationType(playerX, playerY);
    if (locationType > 4)
    {
        locationType++;
    }
    Player player = getPlayer();
    this->playerX = playerX;
    this->playerY = playerY;
    Item *foundItem = items[locationType];
    std::cout << "\nYou found: " << foundItem->getName() << "!\n";
    player.addToInventory(new Item(*foundItem));
    collectedItems[locationType] = true;

    if (foundItem->getName() == "IDCard")
        hasIDCard = true;
    if (foundItem->getName() == "Diary")
        hasDiary = true;

    inSpecimenRoom = (locationType == 5);

    this->player = player;
}

void GameController::handleDemonEncounter()
{
    if (!inSpecimenRoom || !hasDiary)
        return;

    time_t now = time(nullptr);
}

bool GameController::checkSimpleEnding() const
{
    return hasIDCard && (playerX == 0) && (playerY == 1 || playerY == 7);
}

bool GameController::isGameOver() const
{
    return this->player.getHealth() <= 0 ||
           checkSimpleEnding();
}

void GameController::initializeGame()
{
    std::cout << "Initializing game..." << std::endl;
    std::cout << "Game initialized!" << std::endl
              << std::endl;
    std::cout << "=== Campus Horror Game ===" << std::endl
              << std::endl;
    std::cout << "You're trapped on a deserted campus. Your mission is clear: Find the necessary ID Card and find your way out!" << std::endl;
    std::cout << "Objective: Find ID Card in the office and escape!" << endl;
    char input;
    std::cout << "Watch your health status and search different rooms carefully! Good luck." << std::endl
              << std::endl;

    std::cout << "Watch your health and search carefully! Good luck." << std::endl
              << std::endl;
    std::cout << "Tips:" << std::endl;
    std::cout << "- You can collect items in different locations to help you fight different monsters." << std::endl;
    std::cout << "- Don't engage in battles without items, or you'll be in great danger!" << std::endl
              << std::endl;

    playerX = 0;
    playerY = 1;
    gameMap.add_visted(playerX, playerY);
}

char GameController::processPlayerMove()
{
    char input;
    std::vector<char> movemenu = gameMap.display_menu(playerX, playerY);
    std::cout << "> ";
    std::cin >> input;
    if (input == '!')
    {
        gameMap.show_map();
    }
    bool valid = false;
    for (char option : movemenu)
    {
        if (input == option)
        {
            valid = true;
            break;
        }
    }

    while (!valid)
    {
        std::cout << "Invalid input! Please enter a char in the movemenu." << std::endl;
        std::cout << "> ";
        std::cin >> input;

        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

        valid = false;
        for (char option : movemenu)
        {
            if (input == option)
            {
                valid = true;
                break;
            }
        }
    }

    return input;
}

void GameController::updatePlayerPosition(char input)
{
    int newX = this->playerX;
    int newY = this->playerY;
    switch (input)
    {
    case 'w':
        newX--;
        break;
    case 's':
        newX++;
        break;
    case 'a':
        newY--;
        break;
    case 'd':
        newY++;
        break;
    case 'm':
        newX -= 3;
        break;
    case 'n':
        newX += 3;
        break;
    case 'x':
    {
        if (newX == 0 || newX == 2)
        {
            newX = 1;
        }
        if (newX == 3 || newX == 5)
        {
            newX = 4;
        }
        if (newX == 6 || newX == 8)
        {
            newX = 7;
        }
        break;
    }
    }

    if (newX >= 0 && newX < 9 && newY >= 0 && newY < 9)
    {

        this->playerX = newX;
        this->playerY = newY;
    }
    Location *now_room = gameMap.player_location(playerX, playerY);
    std::cout << now_room->when_enter() << std::endl;
    now_room->in(this->player);
    delete now_room;
    gameMap.add_searched(playerX, playerY);
    gameMap.add_visted(playerX, playerY);
}

void GameController::displayGameState()
{

    std::cout << "\n=== Game State ===\n";
    std::cout << "Health: " << this->player.getHealth() << "/" << this->player.getMaxHealth() << "\n";
    std::cout << "================\n\n";
}

Player &GameController::getPlayer()
{
    return player;
}

Map GameController::getMap()
{
    return this->gameMap;
}

void GameController::gamerun()
{
    std::cout << "Controls: w/a/s/d-move, i-inventory, u-use item, q-quit" << endl;
    std::cout << "Objective: Find ID Card and escape!\n"
              << endl;
    char input;
    std::cout << "Enter command (w/a/s/d/n/m/x to move, i to view inventory, u to use item, q to quit, v tp view current status)" << std::endl
              << std::endl;

    std::cout << "=== Game Start ===" << std::endl;
    while (true)
    {
        input = processPlayerMove();
        if (input == 'w' || input == 'a' || input == 's' || input == 'd' || input == 'n' || input == 'm' || input == 'x')
        {
            updatePlayerPosition(input);
        }
        if (input == 'i')
        {
            player.displayInventory();
        }
        if (input == 'v')
        {
            cout << endl;
            cout << "Current status:" << endl;
            cout << "Name: " << player.getName() << endl;
            cout << "Description: " << player.getDescription() << endl;
            cout << "Health: " << player.getHealth() << endl;
            cout << "maxHealth: " << player.getMaxHealth() << endl;
            cout << "Attack: " << player.getAttackPower() << endl;
            cout << "Defense: " << player.getDefensePower() << endl;
            cout << endl;
        }
        if (input == 'u')
        {
            size_t index = 4;
            player.useItem(index);
            std::cout << "You used a snack";
                }
        if (input == 'q')
        {
            cout << "Exiting game..." << endl;
            break;
        }
        if (input == 'l')
        {
            gameMap.show_location(playerX, playerY);
        }
        if (this->checkSimpleEnding())
        {
            std::cout << "\nYOU ESCAPED! (Simple Ending)\n";
            return;
        }

        if (player.getHealth() <= 0)
        {
            std::cout << "\nGAME OVER - You died!\n";
            return;
        }

        if (player.success == true && gameMap.player_location(playerX, playerY)->getName() == "School Hall")
        {
            std::cout << "Congratulations on escaping from this haunted campus !" << std::endl;
            std::cout << "Mission accomplished.But is the game truly over ?" << std::endl;
            std::cout << "Is this really the ending you wanted?" << std::endl;
            return;
        }
        std::cout << "================\n\n";
    }
}